import java.awt.Dimension;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.Insets;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;

import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JOptionPane;
import javax.swing.JPanel;

/** A class used to change the key bindings
 *  @author crezax
 */

public class KeyBindings extends JFrame {

	/**
	 * 
	 */
	private static final long serialVersionUID = 3220728965659645160L;
	private JPanel jContentPane = null;
	private JLabel jLabel = null;
	private JLabel jLabel1 = null;
	private JLabel jLabel2 = null;
	private JLabel jLabel3 = null;
	private JLabel jLabel4 = null;
	private JButton firstPlayerLeft = null;
	private JButton firstPlayerRight = null;
	private JButton firstPlayerUp = null;
	private JButton firstPlayerDown = null;
	private JLabel jLabel6 = null;
	private JButton secondPlayerLeft = null;
	private JButton secondPlayerRight = null;
	private JButton secondPlayerUp = null;
	private JButton secondPlayerDown = null;
	private Controls P1, P2;
	private Game game;
	/**
	 * Constructor, that requires a Game instance to be given. If null reference is given whiles there is a game running, key bindings won't be updated in that game until game is reset.
	 * 
	 */
	public KeyBindings(Game game) {
		super();
		this.game = game;
		initialize();
	}

	/**
	 * This method initializes this
	 * 
	 */
	private void initialize() {
		try {
			ObjectInputStream o = new ObjectInputStream(new FileInputStream("Data/controls.dat"));
			P1 = (Controls) o.readObject();
			P2 = (Controls) o.readObject();
		} catch (FileNotFoundException e) {
			JOptionPane.showMessageDialog(this, "Control files could not be found.\nReinstall application.", "ERROR", JOptionPane.ERROR_MESSAGE);
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (ClassNotFoundException e) {
			JOptionPane.showMessageDialog(this, "Control files have been corrupted.\nReinstall application.", "ERROR", JOptionPane.ERROR_MESSAGE);
		}
        this.setSize(new Dimension(364, 237));
        this.setTitle("Key Bindings");
        this.setContentPane(getJContentPane());
		this.setVisible(true);
		this.setFocusable(true);
	
	}
	
	private void refreshButtonText(){
		firstPlayerLeft.setText(KeyEvent.getKeyText(P1.left()));
		firstPlayerRight.setText(KeyEvent.getKeyText(P1.right()));
		firstPlayerUp.setText(KeyEvent.getKeyText(P1.up()));
		firstPlayerDown.setText(KeyEvent.getKeyText(P1.down()));
		secondPlayerLeft.setText(KeyEvent.getKeyText(P2.left()));
		secondPlayerRight.setText(KeyEvent.getKeyText(P2.right()));
		secondPlayerUp.setText(KeyEvent.getKeyText(P2.up()));
		secondPlayerDown.setText(KeyEvent.getKeyText(P2.down()));
	}
	
	/** A method used to update changed key bindings.
	 * 
	 * @author crezax
	 * @param P1 Controls object containing informations on first player's key bindings
	 * @param P2 Controls object containing informations on second player's key bindings
	 */
	private void updateControls(Controls P1, Controls P2) {
		try {
			new File("Data/controls.dat").delete();
			ObjectOutputStream o = new ObjectOutputStream(new FileOutputStream("Data/controls.dat"));
			o.writeObject(P1);
			o.writeObject(P2);
		} 
		catch (FileNotFoundException e) {} 
		catch (IOException e) {}
	}

	/**
	 * This method initializes jContentPane	
	 * 	
	 * @return javax.swing.JPanel	
	 */
	private JPanel getJContentPane() {
		if (jContentPane == null) {
			GridBagConstraints gridBagConstraints14 = new GridBagConstraints();
			gridBagConstraints14.gridx = 7;
			gridBagConstraints14.fill = GridBagConstraints.BOTH;
			gridBagConstraints14.insets = new Insets(0, 25, 0, 25);
			gridBagConstraints14.ipadx = 20;
			gridBagConstraints14.ipady = 10;
			gridBagConstraints14.gridy = 2;
			GridBagConstraints gridBagConstraints13 = new GridBagConstraints();
			gridBagConstraints13.gridx = 7;
			gridBagConstraints13.fill = GridBagConstraints.BOTH;
			gridBagConstraints13.insets = new Insets(0, 25, 0, 25);
			gridBagConstraints13.ipadx = 20;
			gridBagConstraints13.ipady = 10;
			gridBagConstraints13.gridy = 1;
			GridBagConstraints gridBagConstraints12 = new GridBagConstraints();
			gridBagConstraints12.gridx = 7;
			gridBagConstraints12.fill = GridBagConstraints.BOTH;
			gridBagConstraints12.insets = new Insets(0, 25, 0, 25);
			gridBagConstraints12.ipadx = 20;
			gridBagConstraints12.ipady = 10;
			gridBagConstraints12.gridy = 6;
			GridBagConstraints gridBagConstraints11 = new GridBagConstraints();
			gridBagConstraints11.gridx = 7;
			gridBagConstraints11.fill = GridBagConstraints.BOTH;
			gridBagConstraints11.insets = new Insets(0, 25, 0, 25);
			gridBagConstraints11.ipadx = 20;
			gridBagConstraints11.ipady = 10;
			gridBagConstraints11.gridy = 3;
			GridBagConstraints gridBagConstraints10 = new GridBagConstraints();
			gridBagConstraints10.gridx = 7;
			gridBagConstraints10.gridwidth = 3;
			gridBagConstraints10.gridy = 0;
			jLabel6 = new JLabel();
			jLabel6.setText("Player 2");
			GridBagConstraints gridBagConstraints8 = new GridBagConstraints();
			gridBagConstraints8.gridx = 1;
			gridBagConstraints8.fill = GridBagConstraints.HORIZONTAL;
			gridBagConstraints8.insets = new Insets(0, 25, 0, 25);
			gridBagConstraints8.ipadx = 20;
			gridBagConstraints8.ipady = 10;
			gridBagConstraints8.gridwidth = 1;
			gridBagConstraints8.weightx = 0.0;
			gridBagConstraints8.gridy = 2;
			GridBagConstraints gridBagConstraints7 = new GridBagConstraints();
			gridBagConstraints7.gridx = 1;
			gridBagConstraints7.fill = GridBagConstraints.HORIZONTAL;
			gridBagConstraints7.insets = new Insets(0, 25, 0, 25);
			gridBagConstraints7.ipadx = 20;
			gridBagConstraints7.ipady = 10;
			gridBagConstraints7.gridwidth = 1;
			gridBagConstraints7.weightx = 0.0;
			gridBagConstraints7.gridy = 1;
			GridBagConstraints gridBagConstraints6 = new GridBagConstraints();
			gridBagConstraints6.gridx = 1;
			gridBagConstraints6.fill = GridBagConstraints.HORIZONTAL;
			gridBagConstraints6.gridwidth = 1;
			gridBagConstraints6.insets = new Insets(0, 25, 0, 25);
			gridBagConstraints6.ipadx = 20;
			gridBagConstraints6.ipady = 10;
			gridBagConstraints6.weightx = 0.0;
			gridBagConstraints6.gridy = 6;
			GridBagConstraints gridBagConstraints5 = new GridBagConstraints();
			gridBagConstraints5.gridx = 1;
			gridBagConstraints5.gridwidth = 1;
			gridBagConstraints5.fill = GridBagConstraints.HORIZONTAL;
			gridBagConstraints5.anchor = GridBagConstraints.CENTER;
			gridBagConstraints5.insets = new Insets(0, 25, 0, 25);
			gridBagConstraints5.ipadx = 20;
			gridBagConstraints5.ipady = 10;
			gridBagConstraints5.weightx = 0.0;
			gridBagConstraints5.gridy = 3;
			GridBagConstraints gridBagConstraints4 = new GridBagConstraints();
			gridBagConstraints4.gridx = 0;
			gridBagConstraints4.gridy = 2;
			jLabel4 = new JLabel();
			jLabel4.setText("Down");
			GridBagConstraints gridBagConstraints3 = new GridBagConstraints();
			gridBagConstraints3.gridx = 0;
			gridBagConstraints3.gridy = 1;
			jLabel3 = new JLabel();
			jLabel3.setText("Up");
			GridBagConstraints gridBagConstraints2 = new GridBagConstraints();
			gridBagConstraints2.gridx = 0;
			gridBagConstraints2.gridy = 6;
			jLabel2 = new JLabel();
			jLabel2.setText("Right");
			GridBagConstraints gridBagConstraints1 = new GridBagConstraints();
			gridBagConstraints1.gridx = 0;
			gridBagConstraints1.gridy = 3;
			jLabel1 = new JLabel();
			jLabel1.setText("Left");
			GridBagConstraints gridBagConstraints = new GridBagConstraints();
			gridBagConstraints.gridx = 1;
			gridBagConstraints.gridwidth = 3;
			gridBagConstraints.gridy = 0;
			jLabel = new JLabel();
			jLabel.setText("Player 1");
			jContentPane = new JPanel();
			jContentPane.setLayout(new GridBagLayout());
			jContentPane.add(jLabel, gridBagConstraints);
			jContentPane.add(jLabel1, gridBagConstraints1);
			jContentPane.add(jLabel2, gridBagConstraints2);
			jContentPane.add(jLabel3, gridBagConstraints3);
			jContentPane.add(jLabel4, gridBagConstraints4);
			jContentPane.add(getFirstPlayerLeft(), gridBagConstraints5);
			jContentPane.add(getFirstPlayerRight(), gridBagConstraints6);
			jContentPane.add(getFirstPlayerUp(), gridBagConstraints7);
			jContentPane.add(getFirstPlayerDown(), gridBagConstraints8);
			jContentPane.add(jLabel6, gridBagConstraints10);
			jContentPane.add(getSecondPlayerLeft(), gridBagConstraints11);
			jContentPane.add(getSecondPlayerRight(), gridBagConstraints12);
			jContentPane.add(getSecondPlayerUp(), gridBagConstraints13);
			jContentPane.add(getSecondPlayerDown(), gridBagConstraints14);
			jContentPane.setFocusable(true);
		}
		return jContentPane;
	}
	

	/**
	 * This method initializes firstPlayerLeft	
	 * 	
	 * @return javax.swing.JButton	
	 */
	private JButton getFirstPlayerLeft() {
		if (firstPlayerLeft == null) {
			firstPlayerLeft = new JButton();
			firstPlayerLeft.setText(KeyEvent.getKeyText(P1.left()));
			firstPlayerLeft.addActionListener(new java.awt.event.ActionListener() {
				public void actionPerformed(java.awt.event.ActionEvent e) {
					KeyListener keyListener = new KeyListener(){

						@Override
						public void keyPressed(KeyEvent e) {
							P1.setLeft(e.getKeyCode());
							refreshButtonText();
							updateControls(P1, P2);
							if (game != null) game.reloadControls();
							firstPlayerLeft.removeKeyListener(this);
						}

						@Override
						public void keyReleased(KeyEvent e) {}

						@Override
						public void keyTyped(KeyEvent e) {}
					};
					firstPlayerLeft.setFocusable(true);
					firstPlayerLeft.addKeyListener(keyListener);
				}
			});
		}
		return firstPlayerLeft;
	}

	/**
	 * This method initializes firstPlayerRight	
	 * 	
	 * @return javax.swing.JButton	
	 */
	private JButton getFirstPlayerRight() {
		if (firstPlayerRight == null) {
			firstPlayerRight = new JButton();
			firstPlayerRight.setText(KeyEvent.getKeyText(P1.right()));
			firstPlayerRight.addActionListener(new java.awt.event.ActionListener() {
				public void actionPerformed(java.awt.event.ActionEvent e) {
					KeyListener keyListener = new KeyListener(){

						@Override
						public void keyPressed(KeyEvent e) {
							P1.setRight(e.getKeyCode());
							refreshButtonText();
							updateControls(P1, P2);
							if (game != null) game.reloadControls();
							firstPlayerRight.removeKeyListener(this);
						}

						@Override
						public void keyReleased(KeyEvent e) {}

						@Override
						public void keyTyped(KeyEvent e) {}
					};
					firstPlayerRight.setFocusable(true);
					firstPlayerRight.addKeyListener(keyListener);
				}
			});
		}
		return firstPlayerRight;
	}

	/**
	 * This method initializes firstPlayerUp	
	 * 	
	 * @return javax.swing.JButton	
	 */
	private JButton getFirstPlayerUp() {
		if (firstPlayerUp == null) {
			firstPlayerUp = new JButton();
			firstPlayerUp.setText(KeyEvent.getKeyText(P1.up()));;
			firstPlayerUp.addActionListener(new java.awt.event.ActionListener() {
				public void actionPerformed(java.awt.event.ActionEvent e) {
					KeyListener keyListener = new KeyListener(){

						@Override
						public void keyPressed(KeyEvent e) {
							P1.setUp(e.getKeyCode());
							refreshButtonText();
							updateControls(P1, P2);
							if (game != null) game.reloadControls();
							firstPlayerUp.removeKeyListener(this);
						}

						@Override
						public void keyReleased(KeyEvent e) {}

						@Override
						public void keyTyped(KeyEvent e) {}
					};
					firstPlayerUp.setFocusable(true);
					firstPlayerUp.addKeyListener(keyListener);
				}
			});
		}
		return firstPlayerUp;
	}

	/**
	 * This method initializes firstPlayerDown	
	 * 	
	 * @return javax.swing.JButton	
	 */
	private JButton getFirstPlayerDown() {
		if (firstPlayerDown == null) {
			firstPlayerDown = new JButton();
			firstPlayerDown.setText(KeyEvent.getKeyText(P1.down()));
			firstPlayerDown.addActionListener(new java.awt.event.ActionListener() {
				public void actionPerformed(java.awt.event.ActionEvent e) {
					KeyListener keyListener = new KeyListener(){

						@Override
						public void keyPressed(KeyEvent e) {
							P1.setDown(e.getKeyCode());
							refreshButtonText();
							updateControls(P1, P2);
							if (game != null) game.reloadControls();
							firstPlayerDown.removeKeyListener(this);
						}

						@Override
						public void keyReleased(KeyEvent e) {}

						@Override
						public void keyTyped(KeyEvent e) {}
					};
					firstPlayerDown.setFocusable(true);
					firstPlayerDown.addKeyListener(keyListener);
				}
			});
		}
		return firstPlayerDown;
	}

	/**
	 * This method initializes secondPlayerLeft	
	 * 	
	 * @return javax.swing.JButton	
	 */
	private JButton getSecondPlayerLeft() {
		if (secondPlayerLeft == null) {
			secondPlayerLeft = new JButton();
			secondPlayerLeft.setText(KeyEvent.getKeyText(P2.left()));
			secondPlayerLeft.addActionListener(new java.awt.event.ActionListener() {
				public void actionPerformed(java.awt.event.ActionEvent e) {
					KeyListener keyListener = new KeyListener(){

						@Override
						public void keyPressed(KeyEvent e) {
							P2.setLeft(e.getKeyCode());
							refreshButtonText();
							updateControls(P1, P2);
							if (game != null) game.reloadControls();
							secondPlayerLeft.removeKeyListener(this);
						}

						@Override
						public void keyReleased(KeyEvent e) {}

						@Override
						public void keyTyped(KeyEvent e) {}
					};
					secondPlayerLeft.setFocusable(true);
					secondPlayerLeft.addKeyListener(keyListener);
				}
			});
		}
		return secondPlayerLeft;
	}

	/**
	 * This method initializes secondPlayerRight	
	 * 	
	 * @return javax.swing.JButton	
	 */
	private JButton getSecondPlayerRight() {
		if (secondPlayerRight == null) {
			secondPlayerRight = new JButton();
			secondPlayerRight.setText(KeyEvent.getKeyText(P2.right()));
			secondPlayerRight.addActionListener(new java.awt.event.ActionListener() {
				public void actionPerformed(java.awt.event.ActionEvent e) {
					KeyListener keyListener = new KeyListener(){

						@Override
						public void keyPressed(KeyEvent e) {
							P2.setRight(e.getKeyCode());
							refreshButtonText();
							updateControls(P1, P2);
							if (game != null) game.reloadControls();
							secondPlayerRight.removeKeyListener(this);
						}

						@Override
						public void keyReleased(KeyEvent e) {}

						@Override
						public void keyTyped(KeyEvent e) {}
					};
					secondPlayerRight.setFocusable(true);
					secondPlayerRight.addKeyListener(keyListener);
				}
			});
		}
		return secondPlayerRight;
	}

	/**
	 * This method initializes secondPlayerUp	
	 * 	
	 * @return javax.swing.JButton	
	 */
	private JButton getSecondPlayerUp() {
		if (secondPlayerUp == null) {
			secondPlayerUp = new JButton();
			secondPlayerUp.setText(KeyEvent.getKeyText(P2.up()));
			secondPlayerUp.addActionListener(new java.awt.event.ActionListener() {
				public void actionPerformed(java.awt.event.ActionEvent e) {
					KeyListener keyListener = new KeyListener(){

						@Override
						public void keyPressed(KeyEvent e) {
							P2.setUp(e.getKeyCode());
							refreshButtonText();
							updateControls(P1, P2);
							if (game != null) game.reloadControls();
							secondPlayerUp.removeKeyListener(this);
						}

						@Override
						public void keyReleased(KeyEvent e) {}

						@Override
						public void keyTyped(KeyEvent e) {}
					};
					secondPlayerUp.setFocusable(true);
					secondPlayerUp.addKeyListener(keyListener);
				}
			});
		}
		return secondPlayerUp;
	}

	/**
	 * This method initializes secondPlayerDown	
	 * 	
	 * @return javax.swing.JButton	
	 */
	private JButton getSecondPlayerDown() {
		if (secondPlayerDown == null) {
			secondPlayerDown = new JButton();
			secondPlayerDown.setText(KeyEvent.getKeyText(P2.down()));
			secondPlayerDown.addActionListener(new java.awt.event.ActionListener() {
				public void actionPerformed(java.awt.event.ActionEvent e) {
					KeyListener keyListener = new KeyListener(){

						@Override
						public void keyPressed(KeyEvent e) {
							P2.setDown(e.getKeyCode());
							refreshButtonText();
							updateControls(P1, P2);
							if (game != null) game.reloadControls();
							secondPlayerDown.removeKeyListener(this);
						}

						@Override
						public void keyReleased(KeyEvent e) {}

						@Override
						public void keyTyped(KeyEvent e) {}
					};
					secondPlayerDown.setFocusable(true);
					secondPlayerDown.addKeyListener(keyListener);
				}
			});
		}
		return secondPlayerDown;
	}

	
}  //  @jve:decl-index=0:visual-constraint="92,5"
